#include <seminix/syscall.h>
#include <seminix/tcb.h>
#include <cap/cap.h>
#include <cap/signal.h>

void force_sig(int sig, struct tcb *p)
{

}

void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
{
}

bool get_signal(struct ksignal *ksig)
{
    if (ksig)
        return false;
    return true;
}

int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *from)
{
    return 0;
}

int restore_altstack(const stack_t __user *uss)
{
    return 0;
}

int __save_altstack(stack_t __user *uss, unsigned long sp)
{
    return 0;
}

/**
 * set_current_blocked - change current->blocked mask
 * @newset: new mask
 *
 * It is wrong to change ->blocked directly, this helper should be used
 * to ensure the process can't miss a shared signal we are going to block.
 */
void set_current_blocked(sigset_t *newset)
{

}

long do_no_restart_syscall(struct restart_block *param)
{
	return -EINTR;
}

int force_sig_fault(int sig, int code, void __user *addr, struct tcb *t, const char *reason)
{
    panic("%s %p %s\n", __func__, addr, reason);
    return 0;
}

int send_sig_fault(int sig, int code, void __user *addr, struct tcb *t)
{
    panic("%s %p\n", __func__, addr);
    return 0;
}

const struct cap_ops signal_cap_ops = {
};

SYSCALL_DEFINE3(send_signal, int, sigctl, int, tcb, int, signal)
{
    return 0;
}

SYSCALL_DEFINE2(set_sigaction, int, signal, seminix_sigaction_t __user *, action)
{
    seminix_sigaction_t ac;
    unsigned long sig = signal;

    if (copy_from_user(&ac, action, sizeof (ac)))
        return -SERRNO_EFAULT;

    spin_lock(&current->sighand.siglock);
    for (int i = 0; i < SEMINIX_SIGNAL_MAX; i++) {
        if (test_bit(i, &sig)) {
            current->sighand.signal |= i;
            current->sighand.action[i].__sa_handler = ac.__sa_handler;
            current->sighand.action[i].__sa_restorer = ac.__sa_restorer;
        }
    }
    spin_unlock(&current->sighand.siglock);

    return 0;
}

SYSCALL_DEFINE1(clear_sigaction, int, signal)
{
    return 0;
}
